package com.zsy._21生产者与消费者问题;

/**
 * 线程通信：生产者与消费者问题
 * 使用 synchronized 关键字配合 wait、notify 方法实现生产者消费者问题
 * <p>
 * 需求：定义一个 num = 0，然后定义两个线程 A，B，执行以下步骤
 * 1. 当 num = 0 时，A 线程执行 num + 1
 * 2. 当 num = 1 时，B 线程执行 num - 1
 * 保证 num = 0
 *
 * @author: zhangshuaiyin
 * @date: 2021/8/27 20:48
 */
public class SynchronizedDemo {
    public static void main(String[] args) {
        Data number = new Data();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.increment();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.decrement();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.increment();
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.decrement();
            }
        }, "D").start();
    }
}

class Data {
    private int number = 0;

    public synchronized void increment() {
        while (number != 0) {
            // 等待, 同步方法锁的是当前实例对象
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number += 1;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }

    public synchronized void decrement() {
        while (number != 1) {
            // 等待, 同步方法锁的是当前实例对象
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number -= 1;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }
}
